/**
 * @filename:IpadUserServiceImpl Mar 4, 2024
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;

import cn.hutool.json.JSONObject;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.domain.SysFile;
import com.wonder.admin.service.SysFileService;
import com.wonder.app.domain.IpadUser;
import com.wonder.app.domain.PrdTaskQty;
import com.wonder.app.mapper.IpadUserDao;
import com.wonder.app.mapper.PrdTaskQtyDao;
import com.wonder.app.service.IpadUserService;
import com.wonder.app.request.IpadUserRequest;
import com.wonder.app.service.PrdTaskQtyService;
import com.wonder.common.common.AjaxMap;
import com.wonder.common.config.WonderConfig;

import java.util.*;

import com.wonder.common.exception.CustomException;
import com.wonder.common.utils.DateUtils;
import com.wonder.common.utils.StringUtils;
import com.wonder.common.utils.file.FileUploadUtils;
import com.wonder.common.utils.file.FileUtils;
import com.wonder.common.utils.file.MimeTypeUtils;
import com.wonder.common.utils.file.OSSServiceUtil;
import com.wonder.framework.aws.service.AwsS3Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.multipart.MultipartFile;

/**   
 * @Description:TODO(用户信息服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class IpadUserServiceImpl  extends ServiceImpl<IpadUserDao, IpadUser> implements IpadUserService  {
    /**
     * Logger
     */
    private static final Logger _logger = LoggerFactory.getLogger(IpadUserServiceImpl.class);

    @Autowired
    private IpadUserDao ipadUserDao;

    @Autowired
    private IpadUserService ipadUserService;

    @Autowired
    private SysFileService sysFileService;

    @Autowired
    private  OSSServiceUtil ossServiceUtil;

    @Autowired
    private  AwsS3Service awsS3Service;

    @Autowired
    private PrdTaskQtyDao prdTaskQtyDao;

    @Autowired
    private PrdTaskQtyService prdTaskQtyService;


    /**
     * 验证用户信息信息
     * 
     * @param ipadUser
     * @param type
     * @return String
     */
    @Override
    public String validate(IpadUser ipadUser,String type){
    
    
       return "";
    }

    @Override
    public IPage<IpadUser> selectList(IpadUserRequest ipadUserRequest, Page<IpadUser> page) {
        LambdaQueryWrapper<IpadUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.orderByDesc(IpadUser::getId);
        Page<IpadUser> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        return selectPage;
    }

    @Override
    public Map<String, Object> updateUser(JSONObject map) {

        Long id = Long.parseLong(map.get("id").toString());
        String fname = map.getStr("fname");
        boolean ismenu = map.getBool("ismenu");
//        String feature = VtuzxUtil.getString(map, "feature");
        //获取Base64图片信息
        String imageBinaryStr = map.getStr("imageBinary");
        Base64.Decoder decoder = Base64.getDecoder();
        IpadUser ipadUser = ipadUserDao.selectById(id);
        if (!VtuzxUtil.isEmpty(fname)){
            ipadUser.setFname(fname);
        }
        if(!VtuzxUtil.isEmpty(ismenu)){
            ipadUser.setIsmenu(ismenu);
        }


        //上传到服务器然后获取到地址
        String imageUrl = "";
        byte[] bytes = null;
        try {
            bytes = decoder.decode(imageBinaryStr);
            for (int i = 0; i < bytes.length; i++){
                if(bytes[i] < 0 ){
                    bytes[i] += 256;
                }
            }
            //将二进制图片转成MultipartFile
            MultipartFile multipartFile = FileUtils.encodeToMultipartFile(bytes);
            imageUrl = uploadFile(multipartFile, "");
        } catch (Exception e){
            e.printStackTrace();
        }
        if (!VtuzxUtil.isEmpty(imageUrl)){
            ipadUser.setFeature(imageUrl);
            ipadUser.setImageBinary(imageBinaryStr);
        }
        boolean res = ipadUserService.updateById(ipadUser);
        Map<String,Object> data = new HashMap<>();
        data.put("status",res);
        data.put("data",ipadUser);
        return data;
    }

    @Override
    public Map<String, Object> getUserWages(Page<IpadUser> page, IpadUserRequest ipadUserRequest) throws Exception {
        //现根据条件查询出员工的信息
        Page<IpadUser> ipadUserPage = ipadUserDao.selectPage(page, null);
        List<IpadUser> records = ipadUserPage.getRecords();
        List<Long> userIdList = new ArrayList<>();
        for (IpadUser user : records){
            Long id = user.getId();
            if (!userIdList.contains(id)){
                userIdList.add(id);
            }
        }
        //根据员工id查询出员工工时,计件等信息
        LambdaQueryWrapper<PrdTaskQty> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.in(PrdTaskQty::getUserid,userIdList);

        if (null != ipadUserRequest.getCreateTime()){
            Date[] createTime = ipadUserRequest.getCreateTime();
            queryWrapper.ge(PrdTaskQty::getCreateTime, DateUtils.dateToStr(createTime[0],"yyyy-MM-dd HH:mm:ss"));
            queryWrapper.le(PrdTaskQty::getCreateTime,DateUtils.dateToStr(createTime[1],"yyyy-MM-dd HH:mm:ss")+ " 23:59:59");
        }
        List<PrdTaskQty> taskQtyList = prdTaskQtyDao.selectList(queryWrapper);
        Map<String,Object> userMap = new HashMap<>();//key:员工id value:员工计件工资
        for (PrdTaskQty taskQty : taskQtyList){
            Integer userid = taskQty.getUserid();
            Long workQty = taskQty.getWorkQty();//计件数量
            Double price = taskQty.getPrice();//计件单价
            Double pieceWage = 0.0;
            if(workQty != null && price == null){
                pieceWage = price * workQty;
            }
            Double userPiece = (Double) userMap.get(userid.toString());
            if (null == userPiece ){//如果当前用户有数据,相加
                userMap.put(userid.toString(),pieceWage);
            } else {
                userMap.put(userid.toString(),pieceWage + userPiece);
            }
        }
        //循环用户集合添加计件工资信息以及应发工资
        for (IpadUser user : records){
            Long id = user.getId();
            Double pieceWage = (Double) userMap.get(id.toString());
            user.setPieceWage(pieceWage);
        }

        Map<String,Object> data = new HashMap<>();
        data.put("data",records);
        data.put("total",ipadUserPage.getTotal());
        return data;
    }

    @Override
    public Map<String, Object> getUserList(JSONObject map) throws Exception {
        if (null == map || map.size() == 0){
            throw new CustomException("参数不能为空");
        }
        int start = map.getInt("start");
        int limit = map.getInt("limit");

        Page<IpadUser> page = new Page<IpadUser>(start, limit);
        LambdaQueryWrapper<IpadUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(IpadUser::getPostDept,"生产部").eq(IpadUser::getForbidStatus,true);
        Page<IpadUser> ipadUserPage = ipadUserDao.selectPage(page, wrapper);
        List<IpadUser> records = ipadUserPage.getRecords();
        for (IpadUser user : records){
            String url = user.getFeature();
            if (!StringUtils.isEmpty(url)){
                byte[] fileStream = FileUtils.getFileStream(url);
                String base64Str = Base64.getEncoder().encodeToString(fileStream);
                user.setImageBinary(base64Str);
            }
        }
        Map<String,Object> retMap = new HashMap<>();
        retMap.put("data", records);
        return retMap;
    }

    @Override
    public Map<String, Object> dumpdata(IpadUserRequest ipadUserRequest) {
        Page<IpadUser> page = new Page<IpadUser>(ipadUserRequest.getPage(), ipadUserRequest.getLimit());
        //现根据条件查询出员工的信息
        Page<IpadUser> ipadUserPage = ipadUserDao.selectPage(page, null);
        List<IpadUser> records = ipadUserPage.getRecords();
        List<Long> userIdList = new ArrayList<>();
        for (IpadUser user : records){
            Long id = user.getId();
            if (!userIdList.contains(id)){
                userIdList.add(id);
            }
        }
        //根据员工id查询出员工工时,计件等信息
        LambdaQueryWrapper<PrdTaskQty> queryWrapper = new LambdaQueryWrapper<>();
        if (userIdList.size() > 0){
            queryWrapper.in(PrdTaskQty::getUserid,userIdList);
        }

        if (null != ipadUserRequest.getCreateTime()){
            Date[] createTime = ipadUserRequest.getCreateTime();
            queryWrapper.ge(PrdTaskQty::getCreateTime, DateUtils.dateToStr(createTime[0],"yyyy-MM-dd HH:mm:ss"));
            queryWrapper.le(PrdTaskQty::getCreateTime,DateUtils.dateToStr(createTime[1],"yyyy-MM-dd HH:mm:ss")+ " 23:59:59");
        }
        List<PrdTaskQty> taskQtyList = prdTaskQtyDao.selectList(queryWrapper);
        Map<String,Object> userMap = new HashMap<>();//key:员工id value:员工计件工资
        for (PrdTaskQty taskQty : taskQtyList){
            Integer userid = taskQty.getUserid();
            Long workQty = taskQty.getWorkQty();//计件数量
            Double price = taskQty.getPrice();//计件单价
            Double pieceWage = 0.0;
            if(workQty != null && price == null){
                pieceWage = price * workQty;
            }
            Double userPiece = (Double) userMap.get(userid.toString());
            if (null == userPiece ){//如果当前用户有数据,相加
                userMap.put(userid.toString(),pieceWage);
            } else {
                userMap.put(userid.toString(),pieceWage + userPiece);
            }
        }
        //循环用户集合添加计件工资信息以及应发工资
        for (IpadUser user : records){
            Long id = user.getId();
            Double pieceWage = (Double) userMap.get(id.toString());
            user.setPieceWage(pieceWage);
        }
        String header="NO.,员工姓名,所属车间,基本工资,绩效工资,岗位工资,职工工资,住房补贴,通勤补贴,岗位津贴,保险补助";
        Map<String,Object> retMap=new HashMap<String, Object>();
        retMap.put("header", StringUtils.split(header, ','));
        retMap.put("filename", "员工工资.xlsx");
        retMap.put("percentage", records.size());
        retMap.put("data", records);
        return AjaxMap.success(retMap);
    }

    /**
     * 文件上传到服务器
     * @param file
     * @param upload_config_id
     * @return
     * @throws Exception
     */
    private  String uploadFile(MultipartFile file, String upload_config_id) throws Exception
    {
        try
        {
            if (!file.isEmpty())
            {
                String fileType=file.getContentType();
                String hd5="";
                //Check the file hash, if the same file existed, then return the file path.
                if(Arrays.asList(MimeTypeUtils.DEFAULT_ALLOWED_IMAGES).contains(fileType)) {
                    hd5=FileUtils.getMd5(file);
                    SysFile existedFile = sysFileService.getOne(new QueryWrapper<SysFile>().eq("hash", hd5));
                    if(existedFile!=null) return existedFile.getFilepath();
                }

                String imgUrl="";
                String uploadType= WonderConfig.getUploadType();
                switch(uploadType){
                    case "ali":
                        imgUrl = ossServiceUtil.uploadAliyun(file);
                        break;
                    case "aws-s3":
                        imgUrl= awsS3Service.upload(file);
                        break;

                    default:
                        // 上传并返回新文件名称
                        imgUrl= FileUploadUtils.upload( file);

                }

                if(Arrays.asList(MimeTypeUtils.DEFAULT_ALLOWED_IMAGES).contains(fileType)) {
                    SysFile newFile=new SysFile();
                    newFile.setFilepath(imgUrl).setHash(hd5);
                    sysFileService.save(newFile);
                }

                return imgUrl;
            }
            return "system.uploadError";
        }
        catch (Exception e)
        {
            return e.getMessage();
        }
    }

}